#include "offlinefiletransferitem.h"
#include "ui_offlinefiletransferitem.h"
#include "../Core/SimpleLogger.h"
#include "../Biz/FileTransfer/BaseFileTransfer.h"
#include "../Biz/FileTransfer/p2pbase.h"
#include "../Biz/FileTransfer/p2s.h"
#include "../Biz/WWCommonUtility.h"

#include <QFileDialog>
#include <QDateTime>
#include <QDesktopServices>
#include <QUrl>

using namespace core;
static LoggerCategory g_log("OfflineFileTransferItem");

OfflineFileTransferItem::OfflineFileTransferItem(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::OfflineFileTransferItem)
{
    ui->setupUi(this);

    QObject::connect(ui->btncancel, SIGNAL(clicked()), SLOT(OnCancel()));
    QObject::connect(ui->btnReject, SIGNAL(clicked()), SLOT(OnReject()));
    QObject::connect(ui->btnSave, SIGNAL(clicked()), SLOT(OnSaveFile()));
    QObject::connect(this, SIGNAL(transferProcessChanged(int)), ui->progressBar, SLOT(setValue(int)));
}

OfflineFileTransferItem::~OfflineFileTransferItem()
{
    delete ui;
}


std::string OfflineFileTransferItem::GetFileName()
{
    return m_saved_data.filename + m_saved_data.fileext;
}
bool OfflineFileTransferItem::IsSender()
{
    return m_saved_data.issender;
}
bool OfflineFileTransferItem::IsValid()
{
    return m_session_valid;
}

void OfflineFileTransferItem::InitFileTransferData(CSFileTransferNotify data)
{
    m_saved_data = data;
    ui->transfer_fileName->setText(QString::fromStdString(data.filename + data.fileext));
    QString directstr;
    if(data.issender)
    {
        directstr = " to " + QString::fromStdString(data.destid) + ":";
        ui->btncancel->setVisible(false);
        ui->btnReject->setVisible(false);
        ui->btnSave->setVisible(false);
    }
    else
    {
        directstr = " from " + QString::fromStdString(data.destid) + ":";
        ui->btncancel->setVisible(false);
        ui->btnReject->setVisible(true);
        ui->btnSave->setVisible(true);
        QDateTime t;
        t.setTime_t(data.fileexpire);
        t.toLocalTime();
        QString expiredate = t.toString("(yyyy-MM-dd)");

        ui->expired_info->setText("Offline File, Expiration Date:" + expiredate);
    }
    ui->btnOpen->setVisible(false);
    ui->transfer_DirectionLabel->setText(directstr);
    ui->transfer_eventInfo->setText("waiting...");
    m_session_valid = true;
}

void OfflineFileTransferItem::ProcessTransferNotify(CSFileTransferNotify fileparam)
{
    if(!m_session_valid)
        return;

    if(fileparam.event_id == CSFileTransferNotify::Trans_error)
    {
        SetTransferErrorInfo(fileparam.notifycode);
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        emit newactivity();
    }
    else if(fileparam.event_id == CSFileTransferNotify::Trans_process)
    {
        ChangeTransferingProcess(fileparam.notifycode/(double)m_saved_data.filesize*100);
    }
    else
    {
        ChangeTransferEvent(fileparam.event_id);
    }
}

void OfflineFileTransferItem::SetTransferErrorInfo(int errcode)
{
    switch(errcode)
    {
    case P2S_SESSION_FAILED:
        ui->transfer_eventInfo->setText("failed to receive.");
        break;
    case P2S_FILE_OPEN_FAILED:
        ui->transfer_eventInfo->setText("open file failed.");
        break;
    case P2S_FILE_TOOBIG:
        ui->transfer_eventInfo->setText("too large file. ");
        break;
    case P2S_FILE_ZERO:
        ui->transfer_eventInfo->setText("file size is zero. ");
        break;
    case P2S_GET_FTS_FAILED:
        ui->transfer_eventInfo->setText("connect sever failed.");
        break;
    default:
        ui->transfer_eventInfo->setText("failed for unknown error. ");
        break;
    }
    g_log.Log(lv_warn, "file transfer error. code:%d", errcode);
}

void OfflineFileTransferItem::ChangeTransferingProcess(int percent)
{
    //g_log.Log(lv_debug, "file transfer percent :%d", percent);
    if(percent < 0)
        percent = 0;
    if(percent > 100)
        percent = 100;
    ui->transfer_eventInfo->setText("Transferring...");
    emit transferProcessChanged(percent);
}

void OfflineFileTransferItem::ChangeTransferEvent(int event)
{
    switch(event)
    {
    case CSFileTransferNotify::Trans_finished:
    {
        emit transferProcessChanged(100);
        ui->transfer_eventInfo->setText("finished.");
        m_session_valid = false;
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
        if(!m_saved_data.issender)
            ui->btnOpen->setVisible(true);
        emit newactivity();
    }
    break;
    case CSFileTransferNotify::Trans_connect:
    {
        ui->transfer_eventInfo->setText("Transferring...");
        ui->btnSave->setVisible(false);
        ui->btnReject->setVisible(false);
    }
    break;
    default:
        break;
    }
    g_log.Log(lv_debug, "got the reportevent:%d in receiver.", event);
}

void OfflineFileTransferItem::OnSaveFile()
{
    // promot a save as dialog
    QString savedpath = QFileDialog::getSaveFileName(this, "save file", QString::fromStdString(utility::GetModulePath() + "/" + m_saved_data.filename +
                                                                                               m_saved_data.fileext));
    if(savedpath.size() < 1)
        return;
    m_saved_data.event_id = CSFileTransferNotify::Trans_accept;
    m_saved_data.recvpath = savedpath.toStdString();
    emit offlineNotifyOtherSide(m_saved_data);
    ui->transfer_eventInfo->setText("connecting...");
    ui->btnSave->setVisible(false);
    ui->btnReject->setVisible(false);
}

void OfflineFileTransferItem::OnCancel()
{

}

void OfflineFileTransferItem::OnReject()
{
    m_saved_data.event_id = CSFileTransferNotify::Trans_rejected;
    emit offlineNotifyOtherSide(m_saved_data);
    ui->transfer_eventInfo->setText("rejected by you.");
    m_session_valid = false;
    ui->btnSave->setVisible(false);
    ui->btnReject->setVisible(false);
}

void OfflineFileTransferItem::on_btnOpen_clicked()
{

    QDesktopServices::openUrl(QUrl("file:///" + QString::fromStdString(m_saved_data.recvpath)));
}
